package com.zc.gateway;

import as.leap.vertx.rpc.impl.RPCClientOptions;
import as.leap.vertx.rpc.impl.VertxRPCClient;
import com.zc.common.ClusterVertx;
import com.zc.common.RPCService;
import com.zc.common.annotations.VerticleMapping;
import com.zc.gateway.verticle.BaseVerticle;
import com.zc.gateway.verticle.HttpServerVerticle;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.core.json.JsonObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.reflections.Reflections;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * <pre>
 * @File：ParamUtil
 * @Version：1.0.0
 * @Author：Neil.Zhou
 * @CreateDate：2016/9/23 16:22
 * @Modify：
 * @ModifyDate：2016/9/23
 * @Descript： 参数 工具类
 * </pre>
 */
public class StartRunner{
    private static Logger logger = LogManager.getLogger(StartRunner.class.getName());
    public static Vertx clusterVertx;
    private static final Reflections reflections = new Reflections("com.zc.gateway");
    public static void main(String[] args) throws Exception {
         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        logger.debug("=======================Runner  Deployment======================");
        VertxOptions vo=new VertxOptions();
        final Vertx vertx=Vertx.vertx(vo);
        clusterVertx= ClusterVertx.getAfreshClusterVertx(vertx,"192.168.10.186");
        vertx.deployVerticle(new HttpServerVerticle(context,vertx));
        registerVerticle(context,vertx);

        RPCClientOptions<RPCService> rpcClientOptions = new RPCClientOptions<RPCService>( ClusterVertx.getClusterVertx()).setBusAddress("rpc.user").setServiceClass(RPCService.class);
        RPCService myService = new VertxRPCClient<>(rpcClientOptions).bindService();
        try {
            myService.asyncService(new JsonObject(),"userInfo", event -> {
                System.out.println("远程调用应用中心userInfo方法1:"+event.result());
            });
            System.out.println("远程调用应用中心userInfo方法:" + myService.futureService(new JsonObject(), "userInfo").get(5000, TimeUnit.MILLISECONDS));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("远程调用失败,{}", e);
        }
    }
    /**
     * 只支持Spring ByName 形式
     * @author Neil.Zhou
     * @createDate 2016/06/12
     * @return List<HashMap>
     */
    private static void registerVerticle(ApplicationContext context,Vertx vertx) {
        logger.debug("Register Service Verticle...");
        Set<Class<?>> verticles = reflections.getTypesAnnotatedWith(VerticleMapping.class);
        String busAddressPrefix="";
        for (Class<?> service : verticles) {
            try {
                if (service.isAnnotationPresent(VerticleMapping.class)) {
                    VerticleMapping routeHandler = service.getAnnotation(VerticleMapping.class);
                    if(StringUtils.isBlank(routeHandler.value())){
                        busAddressPrefix=service.getName();
                    }else{
                        busAddressPrefix=routeHandler.value();
                    }
                    logger.debug("Register Verticl path:{}",busAddressPrefix);
                    vertx.deployVerticle(new BaseVerticle(context,toLowerCaseFirstOne(service.getSimpleName()),busAddressPrefix),new DeploymentOptions());
                }
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("Register Service Error {}", service);
            }
        }
    }
    /**
     * 首字母转小写
     * @author Neil.Zhou
     * @createDate 2016/06/12
     * @return 返回字符串
     */
    public static String toLowerCaseFirstOne(String s)
    {
        if(Character.isLowerCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
    }
}
